<?php


namespace Muyuxuanpay\tool;


class Mtool
{
    /**
     * 求经纬度距离
     * @param array|float[] $location1 数组，必须元素（long经度，lat纬度）
     * @param array|float[] $location2 数组，必须元素（long经度，lat纬度）
     * @param string $unit 距离单位 m=米, km=千米,mi=英里,ft=英尺
     * @return float|int
     */
    public static function getDistance(array $location1=['long'=>0,'lat'=>0],array $location2=['long'=>0,'lat'=>0],string $unit='m'){
        $EARTH_RADIUS = 6378.137;
        $radLat1 = self::rad($location1['lat']);
        $radLat2 = self::rad($location2['lat']);
        $a = $radLat1 - $radLat2;
        $b = self::rad($location1['long']) - self::rad($location2['long']);
        $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
        $s = $s * $EARTH_RADIUS;
        $s = round($s * 10000) / 10000;
        $s = $s*1000;
        if($unit=="km"){
            $s = $s/1000;
        }elseif ($unit=='mi'){
            $s = $s*0.000621371;
        }elseif ($unit=='ft'){
            $s = $s*3.281;
        }
        return $s;
    }
    protected static function rad($d){
        return $d * M_PI / 180.0;
    }

    /**
     * 获取订单编号
     * @param int $num
     * @param string $userId
     * @param string $prefix
     * @return string
     */
    public static function getOrderNum(int $num=15,string $userId='',string $prefix=''){
        $str = $prefix.date('YmdHis').strrev(uniqid($userId));
        while (true){
            if(strlen($str)<$num){
                $str .= strrev(uniqid($userId));
            }else{
                break;
            }
        }
        return mb_substr($str,0,$num);
    }

    /**
     * 获取纯数字订单号
     * @return string
     */
    public static function getNumberNum(string $prefix='')
    {
        if(empty($prefix)){
            $prefix = date('YmdHis');
        }
        if(is_numeric($prefix)){
            $prefix = date('YmdHis');
        }
        return $prefix.strval(round(microtime(true)*1000));
    }

    /**
     * 获取定长的商户号
     * @param int $num 位数
     * @param string $userId 用户id
     * @param string $prefix 前缀
     * @return string
     */
    public static function getMerchant(int $num=15,string $userId='',string $prefix=''){
        if($num>32){
            return '';
        }
        $str = $prefix.date('YmdHis').strrev(uniqid($userId));
        $str = md5($str);
        return mb_substr($str,0,$num);
    }

    /**
     * 加密
     * @param string $passWord 需加密字符串
     * @param string $salt 密码盐
     * @return string
     */
    public static function passWordEncode(string $passWord,string $salt=''){
        $passWord = md5(md5($passWord).$salt);
        return $passWord;
    }

    /**验证密码是否正确
     * @param string $passWord 密码
     * @param string $verify 加密字符串
     * @param string $salt 密码盐
     * @return bool
     */
    public static function PassWordVerify(string $passWord,string $verify,string $salt=''){
        $pas = self::passWordEncode($passWord,$salt);
        if(strval($pas)===strval($verify)){
            return true;
        }else{
            return false;
        }
    }

    /**获取固定长度随机字符串
     * @param int $num 字符串长度
     * @param string $character 可用的字符集
     * @return string
     */
    public static function getRandomStr(int $num=4,string $character=""){
        if(empty($character)){
            $character = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890";
        }
        $count = mb_strlen($character);
        $str = '';
        for ($a=0;$a<$num;$a++){
            $str .= $character[mt_rand(0,$count-1)];
        }
        return $str;
    }

    /**获取子订单号码
     * @param string $hostStr
     * @param int $num
     * @param array $nodHas
     * @return array
     */
    public static function getChildOrderNum(string $hostStr,int $num = 1,array $nodHas=[]){
        $hasnum = 0;
        $strArray = [];
        $start = 0;
        while ($hasnum<$num){
            $newstr = $hostStr.'_'.$start;
            if(!in_array($newstr,$nodHas)){
                $strArray[] = $newstr;
                $hasnum++;
            }
            $start++;
        }
        return $strArray;
    }

    /**
     * 隐藏字符串
     * @Param string $str
     * @Param int $start 起始位置 从0开始计数  负数倒转替换
     * @Param int|string $length 当 $length=string 替换 $key
     * @Param int|string $key 填充的隐藏的字符 默认 *
     * @Param string $charset 可废弃 删除 ($key && $charset = $key) 和 ($charset='utf8') 语句;
     */
    public static function hidenStr($str,$start,$length=0,$key='',$charset='utf8'){
        if(strlen($length) && gettype($length) != "integer"){
            $key && $charset = $key;
            $key = $length;
            $length = 0;
        }
        $Par = $length?[$start,$length]:[$start]; //array_filter([$start,$length]);
        // use $charset;
        //$e or $e = mb_strlen($str);
        //$Par     = [$start,$length,$charset];
        $rep_str = mb_substr($str,...$Par);
        strlen($key) or $key = '*';
        strlen($key) == 1 && $key = str_pad('',mb_strlen($rep_str),$key);
        $start  = strlen(mb_substr($str,0,$start));
        $count  = strlen($rep_str);
        $result = substr_replace($str,$key,$start,$count);
        return $result;
    }

    /**
     * 字符串中包含表情
     * @param string $str
     * @return bool
     */
    public static function haveEmojiChar(string $str){
        $mbLen = mb_strlen($str);
        $strArr = [];
        for ($i = 0; $i < $mbLen; $i++) {
            $strArr[] = mb_substr($str, $i, 1, 'utf-8');
            if (strlen($strArr[$i]) >= 4) {
                return true;
            }
        }
        return false;
    }

    /**
     * 删除字符串表情字符串
     * @param $str
     * @return string
     */
    public static  function removeEmojiChar(string $str){
        $mbLen = mb_strlen($str);
        $strArr = [];
        for ($i = 0; $i < $mbLen; $i++) {
            $mbSubstr = mb_substr($str, $i, 1, 'utf-8');
            if (strlen($mbSubstr) >= 4) {
                continue;
            }
            $strArr[] = $mbSubstr;
        }
        return implode('', $strArr);
    }

    /**
     * 表情字符串加密保存
     * @param string $str
     * @return string
     */
    public static function emojiCharEncode(string $str){
        return base64_encode($str);
    }

    /**
     * 表情字符串解密
     * @param string $str
     * @return string
     */
    public static function emojiCharDecode(string $str){
        $a = base64_decode($str);
        if(empty($a)){
            return $str;
        }
        return $a;
    }
    /**
     * 获取客户端IP
     * @return string
     */
    public static function getIp(){
        $ip = '';
        if (isset($_SERVER)) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } else if (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            } else if(isset($_SERVER['REMOTE_ADDR'])){
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        } else{
            if (getenv("HTTP_X_FORWARDED_FOR")) {
                $ip = getenv("HTTP_X_FORWARDED_FOR");
            } else if (getenv("HTTP_CLIENT_IP")) {
                $ip = getenv("HTTP_CLIENT_IP");
            } else {
                $ip = getenv("REMOTE_ADDR");
            }
        }
        if(empty($ip)){
            $ip = '127.0.0.1';
        }
        return $ip;
    }

    /**
     * 金额转换
     * @param float $price
     * @param $decimal
     * @param $unim
     * @return float|string|void
     */
    public static function priceTonium(float $price,$decimal=2,$unim=""){
        $unimArray = [
            [
                'name'=>'亿',
                'value'=>100000000
            ],
            [
                'name'=>'万',
                'value'=>10000
            ],
            [
                'name'=>'千',
                'value'=>1000
            ]
        ];
        $unimArrayUn = array_column($unimArray,'name');
        if(!empty($unim)){
            if(!in_array($unim,$unimArrayUn)){
                return $price;
            }
        }
        if(!empty($unim)){
            $num = sprintf("%.{$decimal}f",$price/$unimArray[array_search($unim,$unimArrayUn)]['value']);
            return $num.$unim;
        }
        foreach ($unimArray as $item){
            if($price >= $item['value']){
                $num = sprintf("%.{$decimal}f",$price/$item['value']);
                return $num.$item['name'];
            }
        }
    }

    /**
     * 获取百分比(或更小的单位)
     * @param $num
     * @return void
     */
    public static function getPercentageFloat($num)
    {
        if ($num > 0.0001) {
            $num = sprintf("%.2f", $num * 100) . '%';
        } else {
            $arr = [
                100000 => "十万",
                1000000 => "百万",
                10000000 => "千万",
                100000000 => "亿",
                1000000000 => "十亿",
                10000000000 => "百亿",
                100000000000 => "千亿",
                1000000000000 => "兆",
                10000000000000 => "十兆",
                100000000000000 => "百兆",
                1000000000000000 => "千兆",
            ];
            foreach ($arr as $k => $v) {
                if ($num > (1 / $k)) {
                    $num = sprintf("%.2f", $num / (1 / $k)) . "/" . $v;
                    break;
                }
            }
        }
        return $num;
    }

    /**
     * 深度合并数组
     * @param array $baseConfig 要被覆盖的数组
     * @param array $config 要覆盖的数组
     * @return array
     */
    public static function depth_array_merge(array $baseConfig,array $config=[])
    {
        foreach ($config as $k=>$v){
            if(isset($baseConfig[$k])){
                if(is_array($v)){
                    $baseConfig[$k] = self::depth_array_merge($baseConfig[$k],$v);
                }else{
                    $baseConfig[$k] = $v;
                }
            }else{
                $baseConfig[$k] = $v;
            }
        }
        return $baseConfig;
    }

    /**
     * json字符串转数据
     * @param string $str
     * @return array
     */
    public static function json_decode(string $str)
    {
        $str = (array)json_decode($str);
        return $str;
    }

    /**
     * json数据转字符串
     * @param array $data
     * @return false|string
     */
    public static function json_encode(array $data)
    {
        return json_encode($data,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
    }
    public static function get_common($num,$mac_common=1,$max_num=10,$one=true,$format='ABCDEFGHIJKLMNOPQRSTUVWXYZ')
    {
        $hang = ceil($num / ($max_num*$mac_common));
        $array = [];
        $nnum = 0;
        $narray = [];
        for($i=0;$i<$hang;$i++){
            $zhenchu = self::get_my_prefix($i,$format);
            for ($k=1;$k<=$mac_common;$k++){
                for ($j=1;$j<=$max_num;$j++){
                    if($nnum<$num){
                        $new_zhenchu = $zhenchu.$k;
                        $ks = $j>=10?$j:("0".$j);
                        $narray[$new_zhenchu][] = $ks;
                        $array[] = $new_zhenchu.'-'.$ks;
                        $nnum++;
                    }else{
                        break;
                    }
                }
            }
        }
        if($one){
            $narray = $array;
        }
        return $narray;
    }
    protected static function get_my_prefix($nums,$format="ABCDEFGHIJKLMNOPQRSTUVWXYZ",$prefix='')
    {
        $num = intdiv($nums,mb_strlen($format));
        $str = $format[$nums%mb_strlen($format)];
        if($num==0){
            return $str;
        }
        if($num>mb_strlen($format)){
            $str = $prefix.$str;
            return self::get_my_prefix($num,$format,$str);
        }elseif ($num<=mb_strlen($format)){
            $str = $prefix.$format[$num-1].$str;
        }else{
            $str = $prefix.$str;
        }
        return $str;
    }

    /**
     * 大小转字节
     * @param $size
     * @return string
     */
    public static function daxiao_zhuan_zijie($size)
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
        for ($i = 0; $size >= 1024 && $i < 9; $i++) $size /= 1024;
        return round($size, 2).$units[$i];
    }
}